/**
 * 文件名：@ApplicationRefreshedTargetAdviceProcessor.java <br/>
 * 包名：cn.efunbox.afw.web.mvc.springmvc <br/>
 * 项目名：afw-web <br/>
 * @author xtwin <br/>
 */
package cn.efunbox.afw.web.mvc.springmvc;

import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import cn.efunbox.afw.core.advice.TargetAdvice;

/**
 * 类名：ApplicationRefreshedTargetAdviceProcessor  <br />
 *
 * 功能：应用刷新时，执行的处理器
 *
 * @author xtwin <br />
 * 创建时间：2016年8月3日 上午10:53:00  <br />
 * @version 2016年8月3日
 */
public class ApplicationRefreshedTargetAdviceProcessor<T> implements ApplicationListener<ApplicationEvent> {
	
	// 日志记录器
	private static final Logger logger = LoggerFactory.getLogger(ApplicationRefreshedTargetAdviceProcessor.class);

	// 增强映射关系
	protected Map<Class<T>, TargetAdvice<T>> mappings = Collections.emptyMap();

	/**
	 * 功能: 在应用刷新时，根据mappings关系执行增强处理 <br/>
	 * 
	 * 重写：xtwin <br/>
	 * 
	 * @version ：2016年8月3日 上午10:54:10<br/>
	 * 
	 * @param event <br/>
	 * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
	 */
	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		if (event instanceof ContextRefreshedEvent) {
			// 在上下文刷新时，执行
			ApplicationContext ctx = (ApplicationContext) event.getSource();
			
			// 依次检查每个类型
			for (Entry<Class<T>, TargetAdvice<T>> entry : mappings.entrySet()) {
				
				String[] names = ctx.getBeanNamesForType(entry.getKey());
				
				logger.info("advice bean names is : {}", Arrays.toString(names));
				
				if (names.length != 0) {
					for (String name : names) {
						entry.getValue().advice(ctx.getBean(name, entry.getKey()));
					}
				}
			}
		}
	}

	/**
	 * @version 2016年8月3日-上午11:38:29
	 */
	public void setMappings(Map<Class<T>, TargetAdvice<T>> mappings) {
		this.mappings = mappings;
	}
}